﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SchemaRepository.cs" company="Data Ductus Malmö">
//   (c) 2010 - 2012 Data Ductus Malmö AB
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace DataDuctus.Snmp.Persistor.Core.Schema
{
  using System;
  using System.Collections.Generic;

  using Lextm.SharpSnmpLib;
  using Lextm.SharpSnmpLib.Mib;

  /// <summary>
  /// The schema repository.
  /// </summary>
  public class SchemaRepository
  {
    #region Fields

    /// <summary>
    /// The object registry.
    /// </summary>
    private readonly IObjectRegistry objectRegistry = DefaultObjectRegistry.Instance;

    #endregion

    #region Constructors and Destructors

    /// <summary>
    /// Initializes a new instance of the <see cref="SchemaRepository"/> class.
    /// </summary>
    public SchemaRepository()
    {
      this.objectRegistry.OnChanged += this.ObjectRegistryOnChanged;
    }

    #endregion

    #region Public Properties

    /// <summary>
    /// Gets the data source.
    /// </summary>
    public SchemaRepositoryDs DataSource { get; private set; }

    /// <summary>
    /// Gets the root.
    /// </summary>
    public ISchemaItem Root { get; private set; }

    #endregion

    #region Public Methods and Operators

    /// <summary>
    /// The load modules.
    /// </summary>
    /// <param name="path">
    /// The path.
    /// </param>
    /// <param name="searchPattern">
    /// The search pattern.
    /// </param>
    public void LoadModules(string path, string searchPattern)
    {
      this.objectRegistry.CompileFolder(path, searchPattern);
    }

    #endregion

    #region Methods

    /// <summary>
    /// The populate.
    /// </summary>
    /// <param name="childs">
    /// The childs.
    /// </param>
    /// <param name="owner">
    /// The owner.
    /// </param>
    /// <param name="ns">
    /// The ns.
    /// </param>
    private static void Populate(IEnumerable<IDefinition> childs, ISchemaItem owner, string ns)
    {
      if (null == owner.Children)
      {
        owner.Children = new List<ISchemaItem>();
      }

      var ownerChilds = (List<ISchemaItem>)owner.Children;

      foreach (IDefinition entity in childs)
      {
        ISchemaItem newOwner = new EmbeddedEntitySchemaItem(entity, owner, false);

        ownerChilds.Add(newOwner);

        Populate(entity.Children, newOwner, string.IsNullOrEmpty(ns) ? entity.Name : ns + "." + entity.Name);
      }
    }

    /// <summary>
    /// The object registry on changed.
    /// </summary>
    /// <param name="sender">
    /// The sender.
    /// </param>
    /// <param name="e">
    /// The e.
    /// </param>
    private void ObjectRegistryOnChanged(object sender, EventArgs e)
    {
      this.Root = new EmbeddedEntitySchemaItem(this.objectRegistry.Tree.Root, null, true);

      Populate(this.objectRegistry.Tree.Root.Children, this.Root, string.Empty);

      if (null != this.DataSource)
      {
        this.DataSource.ReIndex();
      }
      else
      {
        this.DataSource = new SchemaRepositoryDs(this);
      }
    }

    #endregion
  }
}